#pragma once

#include "../Common/ScannerInterface.h"
#include <thread>
#include <mutex>
#include <atomic>
#include <queue>
#include <condition_variable>
#include <memory>

#ifdef _WIN32
    #include <windows.h>
#else
    #include <dirent.h>
    #include <sys/stat.h>
    #include <unistd.h>
#endif

class FileScanner {
public:
    FileScanner();
    ~FileScanner();

    // 主要接口
    bool startScan(const std::wstring& folderPath);
    void stopScan();
    bool isScanning() const;
    ScanStatus getStatus() const;

    // 回调设置
    void setProgressCallback(ScanProgressCallback callback);
    void setCompleteCallback(ScanCompleteCallback callback);
    
    // C风格回调设置（用于DLL导出）
    void setProgressCallbackC(ProgressCallbackC callback);
    void setCompleteCallbackC(CompleteCallbackC callback);

    // 统计信息
    uint64_t getTotalFilesScanned() const;
    uint64_t getTotalBytesScanned() const;

private:
    // 扫描任务结构
    struct ScanTask {
        std::wstring directoryPath;
        int depth;
        
        ScanTask(const std::wstring& path, int d = 0) 
            : directoryPath(path), depth(d) {}
    };

    // 线程池相关
    static const int MAX_THREADS = 4;
    std::vector<std::thread> workerThreads;
    std::queue<ScanTask> taskQueue;
    std::mutex taskQueueMutex;
    std::condition_variable taskCondition;
    std::atomic<bool> shouldStop;
    std::atomic<bool> scanning;
    std::atomic<ScanStatus> currentStatus;

    // 结果存储
    std::vector<ScanResult> scanResults;
    std::mutex resultsMutex;

    // 统计信息
    std::atomic<uint64_t> totalFilesScanned;
    std::atomic<uint64_t> totalBytesScanned;
    std::atomic<int> activeThreads;

    // 回调函数
    ScanProgressCallback progressCallback;
    ScanCompleteCallback completeCallback;
    ProgressCallbackC progressCallbackC;
    CompleteCallbackC completeCallbackC;
    std::mutex callbackMutex;

    // 私有方法
    void workerThreadFunction();
    void scanDirectory(const std::wstring& directoryPath, int depth);
    void addScanResult(const ScanResult& result);
    void notifyProgress(const std::wstring& filePath, uint64_t fileSize);
    void notifyComplete(ScanStatus status);
    void initializeThreadPool();
    void shutdownThreadPool();
    
#ifdef _WIN32
    bool scanDirectoryWin32(const std::wstring& directoryPath, int depth);
    FILETIME getFileTime(const WIN32_FIND_DATAW& findData);
#else
    bool scanDirectoryPosix(const std::wstring& directoryPath, int depth);
    FILETIME getFileTime(const struct stat& fileStat);
#endif

    // 工具函数
    std::wstring stringToWString(const std::string& str);
    std::string wstringToString(const std::wstring& wstr);
    bool isValidDirectory(const std::wstring& path);
    uint64_t combineFileSize(uint32_t high, uint32_t low);
};